stub.cをCortex-M33 on QEMUで動かす
stub.c をワンパス通す
4649.elf を作成、QEMUで動かしてみる。
code:test/4649.S
.text
.syntax unified
.thumb
.globl min_caml_start
min_caml_start: # main entry point
# main program starts
ldr r0, =4649
bl min_caml_print_int
bl min_caml_print_newline
# main program ends
bx lr
code:stub.c
typedef struct {
volatile uint32_t DATA;
volatile uint32_t STATE;
volatile uint32_t CTRL;
volatile uint32_t INTSTATUS;
volatile uint32_t BAUDDIV;
} UART;
extern void min_caml_start(char *, char *);
static void uart_init(void) {
UART0->CTRL = UART_CTRL_TX_EN | UART_CTRL_RX_EN;
}
static void uart_putc(char c) {
UART0->DATA = (uint32_t)c;
}
static void uart_puts(const char *s) {
while (*s) {
if (*s == '\n') {
uart_putc('\r');
}
uart_putc(*s++);
}
}
void min_caml_print_int(int n) {
char buf12; // enough for 32-bit int int i = 0;
if (n < 0) {
uart_putc('-');
n = -n;
}
do {
n /= 10;
} while (n > 0);
while (i > 0) {
}
}
void min_caml_print_newline(void) {
uart_putc('\n');
}
int main(void) {
uart_init();
uart_puts("Hello from QEMU mps2-an505 Cortex-M33!\n");
min_caml_start(NULL, NULL);
while (1) {
}
}
code:libmincaml.S
.text
.syntax unified
.thumb
.globl foo
foo:
movs r0, 123
bx lr
code:startup.c
extern int main(void);
extern uint32_t _estack;
extern uint32_t _sidata;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
#define SCB_CPACR (*(volatile uint32_t *)0xE000ED88u) void Reset_Handler(void);
void Default_Handler(void) {
while (1) {
}
}
void NMI_Handler(void) __attribute__((weak, alias("Default_Handler")));
void HardFault_Handler(void) __attribute__((weak, alias("Default_Handler")));
void SVC_Handler(void) __attribute__((weak, alias("Default_Handler")));
void PendSV_Handler(void) __attribute__((weak, alias("Default_Handler")));
void SysTick_Handler(void) __attribute__((weak, alias("Default_Handler")));
__attribute__((section(".isr_vector")))
void (* const vector_table[])(void) = {
(void (*)(void))(&_estack),
Reset_Handler,
NMI_Handler,
HardFault_Handler,
Default_Handler,
Default_Handler,
Default_Handler,
0,
0,
0,
0,
SVC_Handler,
0,
0,
PendSV_Handler,
SysTick_Handler,
};
void Reset_Handler(void) {
SCB_CPACR |= (0xFu << 20);
__asm__ volatile ("dsb");
__asm__ volatile ("isb");
uint32_t *src = &_sidata;
uint32_t *dst = &_sdata;
while (dst < &_edata) {
*dst++ = *src++;
}
dst = &_sbss;
while (dst < &_ebss) {
*dst++ = 0;
}
main();
while (1) {
}
}
code:qemu.mk
CC = arm-none-eabi-gcc
OBJCOPY = arm-none-eabi-objcopy
CFLAGS = \
-mcpu=cortex-m33 \
-mthumb \
-mfpu=fpv5-sp-d16 \
-mfloat-abi=hard \
-ffreestanding \
-nostdlib \
-Wall \
-Wextra \
-O2
LDFLAGS = \
-T linker.ld \
-nostdlib \
-Wl,-Map=main.map
test/%.o: test/%.S
$(CC) $(CFLAGS) -c -o $@ $<
test/%.elf: test/%.o startup.c stub.c libmincaml.S
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
test/%.res: test/%.elf
qemu-system-arm \
-machine mps2-an505 \
-cpu cortex-m33 \
-m 16M \
-nographic \
-monitor none \
-kernel $<
clean:
rm -f *.o *.elf *.bin *.map
code:linker.ld
ENTRY(Reset_Handler)
MEMORY
{
FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x80000000, LENGTH = 8M
}
PHDRS
{
text PT_LOAD FLAGS(5);
data PT_LOAD FLAGS(6);
}
_estack = ORIGIN(RAM) + LENGTH(RAM);
SECTIONS
{
.isr_vector :
{
KEEP(*(.isr_vector))
} > FLASH :text
.text :
{
*(.text*)
*(.rodata*)
. = ALIGN(4);
_etext = .;
} > FLASH :text
.data : AT(_etext)
{
. = ALIGN(4);
_sdata = .;
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM :data
_sidata = LOADADDR(.data);
.bss (NOLOAD) :
{
. = ALIGN(4);
_sbss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
} > RAM :NONE
}
実行してみる。4649が表示されればOK
code:sh
$ make -f qemu.mk test/4649.res
qemu-system-arm \
-machine mps2-an505 \
-cpu cortex-m33 \
-m 16M \
-nographic \
-monitor none \
-kernel test/4649.elf
Hello from QEMU mps2-an505 Cortex-M33!
4649